<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="React"></div>

<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<!-- jsx转为js -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

<script type="text/babel">

    class Count extends React.Component {

        // 初始化状态
        state = {count: 0}

        // 加1按钮回调
        add = () => {
            let {count} = this.state
            this.setState({count: count + 1})
        }

        death = () => {
            ReactDOM.unmountComponentAtNode(document.getElementById("React"))
        }

        // 强制更新按钮回调
        force = () => {
            this.forceUpdate()
        }

        constructor(props) {
            super(props);
            console.log("1构造器")
        }

        // 组件将要挂载
        componentWillMount() {
            console.log("2componentWillMount组件将要挂载")
        }

        render() {
            let {count} = this.state
            console.log("3render")
            return (
                    <div>
                        <h2>当前求和为{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更改任何状态中的数据，强制更新下</button>
                    </div>
            )
        }

        // 组件挂载完毕
        componentDidMount() {
            console.log("4componentDidMount组件挂载完毕")
        }

        // 应该组件更新, 默认为真，子类重写抽象类的方法进行控制， 说白了就是面向对象的 模版方法设计模式
        shouldComponentUpdate() {
            console.log("shouldComponentUpdate")
            return true
        }

        // 组件将要更新
        componentWillUpdate() {
            console.log("组件将要更新componentWillUpdate")
        }

        // 组件更新完毕
        componentDidUpdate() {
            console.log("组件更新完毕componentDidUpdate")
        }

        // 组件将要卸载
        componentWillUnmount() {
            console.log("componentWillUnmount组件将要卸载")
        }
    }

    class A extends React.Component {
        state = {carName: "朗逸"}

        changeCar = () => {
            this.setState({carName:"帝豪"})
        }

        render() {
            return (
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
            )
        }
    }

    class B extends React.Component {

        // 第一次render不算， 第二次父组件渲染才进入
        componentWillReceiveProps() {
            console.log("B组件 componentWillReceiveProps")
        }

        // 应该组件更新, 默认为真，子类重写抽象类的方法进行控制， 说白了就是面向对象的 模版方法设计模式
        shouldComponentUpdate() {
            console.log("B组件 shouldComponentUpdate")
            return true
        }

        // 组件将要更新
        componentWillUpdate() {
            console.log("B组件 组件将要更新componentWillUpdate")
        }

        // 组件更新完毕
        componentDidUpdate() {
            console.log("B组件 组件更新完毕componentDidUpdate")
        }

        render() {
            console.log("B组件 render")
            return (
                    <div>我是B组件, 接收到的车是：{this.props.carName}</div>
            )
        }
    }

    ReactDOM.render(<A/>, document.getElementById("React"))
</script>
</body>
</html>